///////////////////////////////////////////////////////////////////////////////////////////////////
/// \file formic/wfn/data.cpp
///
/// \brief   implementation file for the wavefunction data class
///
///////////////////////////////////////////////////////////////////////////////////////////////////

#include<formic/wfn/data.h>
#include<formic/archive.h>
#include<formic/mpi/interface.h>

///////////////////////////////////////////////////////////////////////////////////////////////////
/// \brief constructs the data object
///
/// \param[in,out]  arch     an archive holding the data object
///
///////////////////////////////////////////////////////////////////////////////////////////////////
template <class S> formic::WfnData<S>::WfnData(formic::Archive & arch) {

  // read and broadcast the name, fixed/variable flag, and data vector
  formic::mpi::read_and_bcast(arch, _name, "Failed to read name in WfnData constructor.");
  formic::mpi::read_and_bcast(arch, _fixed, "Failed to read fixed/variable flag in WfnData constructor.");
  formic::mpi::read_and_bcast(arch, _data_vec, "Failed to read data vector in WfnData constructor.");

}

template formic::WfnData<int>::WfnData(formic::Archive &);
template formic::WfnData<double>::WfnData(formic::Archive &);
template formic::WfnData<std::complex<double> >::WfnData(formic::Archive &);

///////////////////////////////////////////////////////////////////////////////////////////////////
/// \brief constructs the data object with a uniform vector
///
/// \param[in]      name     the name for the data object
/// \param[in]      fixed    whether the data is to be fixed or variable
/// \param[in]      n        the size to make the data vector
/// \param[in]      val      the value with which to fill the data vector
///
///////////////////////////////////////////////////////////////////////////////////////////////////
template <class S> formic::WfnData<S>::WfnData(const std::string & name, const bool fixed, const int n, const S val)
: _name(name),
  _fixed(fixed),
  _data_vec(n, val)
{}

template formic::WfnData<int>::WfnData(const std::string &, const bool, const int, const int);
template formic::WfnData<double>::WfnData(const std::string &, const bool, const int, const double);
template formic::WfnData<std::complex<double> >::WfnData(const std::string &, const bool, const int, const std::complex<double>);

///////////////////////////////////////////////////////////////////////////////////////////////////
/// \brief converts the object into the command that will create the object
///
/// \param[in,out]  arch     an archive in which to store the command
///
///////////////////////////////////////////////////////////////////////////////////////////////////
template <class S> void formic::WfnData<S>::to_command(formic::Archive & arch) const {

  // write keyword
  arch << this->command_name(S()) << std::endl;

  // write the name
  arch << _name << std::endl;

  // write whether the data is fixed or variable
  arch << _fixed << std::endl;

  // write the data
  arch << _data_vec << std::endl;

}

template void formic::WfnData<int>::to_command(formic::Archive &) const;
template void formic::WfnData<double>::to_command(formic::Archive &) const;
template void formic::WfnData<std::complex<double> >::to_command(formic::Archive &) const;
